package com.slb.slnwp.common.utils;

import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: joinly
 * @date: 2021-10-10 17:36:44
 * @desc: 时间工具类
 **/
public class DateUtil {

    final static public String HH_DATA_FORMAT = "yyyyMMdd";

    final static public String DATA_FORMAT = "yyyyMMddHH";

    final static public String FULL_ST_FORMAT = "yyyyMMddHHmmss";

    final static public String FULL_STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";

    final static public String FULL_STANDARD_FORMAT_HH = "yyyy-MM-dd HH:mm";

    final static public String NC_ST_FORMAT = "yyyy-MM-dd_HH:mm:ss";

    final static public String NC_ST_FORMAT_HH = "MM月dd日HH时";

    /**
     * 获取传入的两个时间之间的时间差，结果可选择为差距的天数，小时数或者分钟数
     * @param type  1天数 2小时数 3分钟数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param timeFormat "1" yyyyMMddHHmmss "2" yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static int getTimesDiff(int type, String startTime, String endTime, String timeFormat) {
        Map<String, String> timeFormatMap = new HashMap<>();
        // 不同的时间类型
        timeFormatMap.put("1",FULL_ST_FORMAT);// yyyyMMddHHmmss
        timeFormatMap.put("2",FULL_STANDARD_FORMAT);// yyyy-MM-dd HH:mm:ss
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            try {
                // 使用SimpleDateFormat类进行时间计算
                SimpleDateFormat sdf = new SimpleDateFormat(timeFormatMap.get(timeFormat));
                long from = sdf.parse(startTime).getTime();
                long to = sdf.parse(endTime).getTime();
                int times = 0;
                // 根据需求，将结果转换天，小时，分钟返回
                if (type == 1) {
                    times = (int) ((to - from) / (1000 * 60 * 60 * 24));
                } else if (type == 2) {
                    times = (int) ((to - from) / (1000 * 60 * 60));
                } else if (type == 3) {
                    times = (int) ((to - from) / (1000 * 60));
                }
                return times;
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return -1;
    }

    /**
     * 计算传入的两个时间的时间差（分+秒），返回结果为，x分x秒，连带着
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     */
    public static String getTimesDiff1(String startTime, String endTime) {
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            try {
                // 将类型转换为"yyyy-MM-dd HH:mm:ss"，进行计算
                SimpleDateFormat sdf = new SimpleDateFormat(FULL_STANDARD_FORMAT);// FULL_STANDARD_FORMAT
                long from = sdf.parse(startTime).getTime();
                long to = sdf.parse(endTime).getTime();
                String times = "";
                // 计算时间差，分+秒
                int timesFen = (int) ((to - from) / (1000 * 60));
                int timesMiao = (int) (((to - from) % (1000 * 60)) / 1000);
                times = timesFen + "分" + timesMiao + "秒";
                return times;
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    /**
     * 取传入的两个时间之间的时间差，结果可选择为差距的天数，小时数，分钟数以及秒数
     *
     * @param type      1天数 2小时数 3分钟数 4秒数
     * @param startTime
     * @param endTime
     * @return
     */
    public static int getTimesDiff2(int type, String startTime, String endTime, String timeType) {
        Map<String, String> timeFormatMap = new HashMap<>();
        // 不同的时间类型
        timeFormatMap.put("1",FULL_ST_FORMAT);// yyyyMMddHHmmss
        timeFormatMap.put("2",FULL_STANDARD_FORMAT);// yyyy-MM-dd HH:mm:ss
        timeFormatMap.put("3",DATA_FORMAT);// yyyyMMddHH
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            try {
                // 使用SimpleDateFormat类进行时间计算
                SimpleDateFormat sdf = new SimpleDateFormat(timeFormatMap.get(timeType));
                long from = sdf.parse(startTime).getTime();
                long to = sdf.parse(endTime).getTime();
                int times = 0;
                // 根据需求，将结果转换天，小时，分钟，秒数返回
                if (type == 1) {
                    times = (int) ((to - from) / (1000 * 60 * 60 * 24));
                } else if (type == 2) {
                    times = (int) ((to - from) / (1000 * 60 * 60));
                } else if (type == 3) {
                    times = (int) ((to - from) / (1000 * 60));
                } else if (type == 4) {
                    times = (int) ((to - from) / (1000));
                }
                return times;
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return -1;
    }

    /**
     * 用于格式化日期的方法。传入一个Date对象和一个日期格式字符串作为参数，
     * 返回一个按指定格式格式化后的日期字符串
     * @param date 传入的时间
     * @param format 指定转换的类型
     * @return
     */
    public static String formatTime(Date date, String format) {
        // 如果传入的日期对象为null，则返回空字符串
        if (date == null) {
            return "";
        }
        // 如果传入的日期格式字符串为空，则使用默认的日期格式常量FULL_STANDARD_FORMAT
        if (format.equals("")) {
            format = FULL_STANDARD_FORMAT;
        }
        // 使用SimpleDateFormat类按指定格式进行日期格式化
        SimpleDateFormat ft = new SimpleDateFormat(format);
        return ft.format(date);
    }

    /**
     * 将日期字符串转换为另一种日期格式的方法
     * 传入一个日期字符串和目标日期格式字符串作为参数
     * @param str
     * @param format
     * @return
     */
    public static String converseStr(String str, String format) {
        // 使用指定的日期格式常量FULL_ST_FORMAT创建SimpleDateFormat对象
        SimpleDateFormat sdf = new SimpleDateFormat(FULL_ST_FORMAT);
        Date date = null;
        try {
            date = sdf.parse(str);
            // 如果解析失败，返回空字符串
        } catch (ParseException e) {
            return "";
        }
        // 使用formatTime方法将Date对象按照目标格式进行格式化
        return formatTime(date, format);
    }

    /**
     * 包含两个方法，它们都用于获取当前日期时间的字符串表示，但允许使用不同的日期时间格式
     * @param format 用于指定日期时间的格式
     * @return
     */
    public static String getNow(String format) {
        if (format.equals("")) {
            format = FULL_STANDARD_FORMAT;
        }
        // 创建 SimpleDateFormat 对象，使用指定的或默认的格式
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date());
    }
    public static String getNow() {
        SimpleDateFormat sdf = new SimpleDateFormat(FULL_ST_FORMAT);
        // 使用 format 方法将当前日期时间格式化为字符串并返回。
        return sdf.format(new Date());
    }

    /**
     * 一个用于在给定的日期上增加指定分钟数的方法
     * @param date
     * @param amount
     * @return
     */
    public static Date addMinute(Date date, int amount) {
        // 创建一个Calendar对象，并将传入的日期设置为该Calendar对象的时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 使用Calendar的add方法增加指定分钟数
        calendar.add(Calendar.MINUTE, amount);
        // 获取增加后的日期
        date = calendar.getTime();
        return date;
    }

    /**
     * 一个用于在给定的日期上增加指定小时数的方法
     * @param date
     * @param amount
     * @return
     */
    public static Date addHour(Date date, int amount) {
        // 创建一个Calendar对象，并将传入的日期设置为该Calendar对象的时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 使用Calendar的add方法增加指定小时数
        calendar.add(Calendar.HOUR_OF_DAY, amount);
        // 获取增加后的日期
        date = calendar.getTime();
        return date;
    }

    /**
     * 一个用于在给定的日期上增加指定天数的方法
     * @param date
     * @param amount
     * @return
     */
    public static Date addDays(Date date, int amount) {
        // 创建一个Calendar对象，并将传入的日期设置为该Calendar对象的时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 使用Calendar的add方法增加指定天数
        calendar.add(Calendar.DAY_OF_MONTH, amount);
        // 获取增加后的日期
        date = calendar.getTime();
        return date;
    }

    /**
     * 将字符串转换为日期对象的方法
     * @param dateStr
     * @return
     */
    public static Date strToDateEx(String dateStr) {
        // 如果传入的日期字符串为null，则返回null
        if (dateStr == null) {
            return null;
        }
        // 使用指定的日期格式常量FULL_ST_FORMAT创建SimpleDateFormat对象
        SimpleDateFormat sdf = new SimpleDateFormat(FULL_ST_FORMAT);
        String str = dateStr;
        try {
            // 使用SimpleDateFormat对象解析日期字符串，返回Date对象
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            // 如果解析失败，打印异常堆栈，并返回null
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 将日期字符串从一种格式转换为另一种格式
     * 转换格式方法1
     * 将2023-07-26 10:55:36格式转换为yyyyMMddHHmmss
     * @param date
     * @return
     */
    public static String timeConversion1(String date) {
        // 使用DateTimeFormatter解析传入的日期字符串为LocalDateTime对象
        LocalDateTime dateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        // 使用DateTimeFormatter将LocalDateTime对象格式化为"yyyyMMddHHmmss"的字符串
        String formattedBeginTime = dateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        return formattedBeginTime;
    }

    /**
     * 将传入的时间，转换为模式用的时次的类型
     * 如：2023-07-26 10:55:36格式转换为2023072610
     * @param date
     * @return
     */
    public static String timeConversionStdt(String date) {
        // 使用DateTimeFormatter解析传入的日期字符串为LocalDateTime对象
        LocalDateTime dateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        // 使用DateTimeFormatter将LocalDateTime对象格式化为"yyyyMMddHH"的字符串
        String formattedBeginTime = dateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHH"));
        // 返回需要的时次
        return formattedBeginTime;
    }


    /**
     * 将日期字符串从一种格式转换为另一种格式
     * 转换格式方法1
     * 将yyyyMMddHHmmss格式转换为2023-07-26 10:55:36
     * @param date
     * @return
     */
    public static String timeConversion2(String date) {
        // 同上
        LocalDateTime dateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String formattedDateTime = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        return formattedDateTime;
    }

    /**
     * 获取上一天时间时次：
     * 用于模式失败，大屏显示上一天内容，获取上一天时次
     * @return
     */
    public static String getPastCurStdt(){
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 计算前一天的日期
        LocalDate previousDay = currentDate.minusDays(1);
        // 格式化前一天的日期为字符串，格式为yyyyMMdd
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formattedDate = previousDay.format(formatter);
        return formattedDate;
    }

    /**
     * 获取当天时间时次：
     * 与上面相对应
     * @return
     */
    public static String getCurStdt(){
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 格式化当前日期为字符串，格式为yyyyMMdd
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formattedDate = currentDate.format(formatter);
        return formattedDate;
    }

    /**
     * 默认返回当天00时
     * 自动拼接00时
     * @return
     */
    public static String currTimeBy00() {
        // 获取当前日期
        Date currentDate = new Date();
        // 创建一个日期格式化对象，指定所需的格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        // 格式化日期为字符串
        String formattedDate = dateFormat.format(currentDate);
        // 拼接 "00" 到格式化后的日期
        formattedDate += "00";
        return formattedDate;
    }

    /**
     * 计算当前时次第一天结束时间
     * @return
     */
    public static String countFirstDay(String stdt) {
        try {
            // 创建日期格式化对象，解析输入的时间字符串
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH");
            Date date = dateFormat.parse(stdt);
            // 使用 Calendar 对象来进行日期操作
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            // 增加36小时
            calendar.add(Calendar.HOUR_OF_DAY, 36);
            // 格式化日期为 "YYYYMMDDHHmmss" 格式
            SimpleDateFormat outputFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            String resultTime = outputFormat.format(calendar.getTime());
            return resultTime;
        } catch (ParseException e) {
            e.printStackTrace();
            return null; // 如果输入时间格式不正确，返回 null 或者适当的错误信息
        }
    }

    /**
     * 将模式的时次转为北京时间
     * 即：默认+8小时
     * @param stdt
     * @return
     */
    public static String convertToBeijingTime(String stdt){
         // 定义输入时间的格式
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyyMMddHH");

        // 解析输入时间字符串为 LocalDateTime 对象
        LocalDateTime dateTime = LocalDateTime.parse(stdt, inputFormatter);

        // 添加8小时，转换为北京时间
        LocalDateTime beijingTime = dateTime.plusHours(8);

        // 定义输出时间的格式
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("MM月dd日HH时");

        // 格式化为北京时间字符串
        return beijingTime.format(outputFormatter);
    }

    /**
     * 计算满足风云四号的时间范围
     * 起始时间是否在 -3392 ~ +208 秒之间，结束时间是否在 -15 ~ +1785 秒之间
     * @param stdt
     * @return
     */
    public static Map<String, LocalDateTime> fyTimeRange(String stdt){
        Map<String, LocalDateTime> timeMap = new HashMap<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHH");
        LocalDateTime checkTime = LocalDateTime.parse(stdt, formatter);
        // 开始时间范围
        LocalDateTime startTimeRangeStart = checkTime.minusSeconds(3392);
        LocalDateTime startTimeRangeEnd = checkTime.plusSeconds(208);
        timeMap.put("ss", startTimeRangeStart);
        timeMap.put("se", startTimeRangeEnd);
        // 结束时间范围
        LocalDateTime endTimeRangeStart = checkTime.minusSeconds(15);
        LocalDateTime endTimeRangeEnd = checkTime.plusSeconds(1785);
        timeMap.put("es", endTimeRangeStart);
        timeMap.put("ee", endTimeRangeEnd);

        return timeMap;
    }

    public static void main(String[] args) {
        Map<String, LocalDateTime> timeMap = fyTimeRange("2024032900");
        System.out.println("timap="+timeMap);
    }

}